#include <stdio.h>
#include "kfifo.h"
#include "main.h"	
#include "earbud_cmd.h"

//LOG
//UART1
//TX:PD5

//EARBUD_TYPE_L
//UART0
//TX:PB4
//RX:PB5

//EARBUD_TYPE_R
//LPUART
//TX:PC5
//RX:PC6


#define UARTx_RX_PORT							GPIOB
#define UARTx_RX_PIN							GPIO_PIN_5
#define UARTx_TX_PIN							GPIO_PIN_4

#define LPUARTx_RX_PORT							GPIOC
#define LPUARTx_RX_PIN							GPIO_PIN_6


UART_HandleTypeDef sUartxHandle;
LPUART_HandleTypeDef sLPUartxHandle;
static GPIO_InitTypeDef gpio_initStruct;

void app_uart_left_tx_enable(void)
{
    /**if UARTx is UART0 
    PB5     ------> UART0_RXD OpenDrain
    PB4     ------> UART0_TXD
    */
    
    GPIO_InitTypeDef gpio_initStruct;
    gpio_initStruct.Pin = GPIO_PIN_5;  
    gpio_initStruct.Mode = GPIO_MODE_INPUT;
	gpio_initStruct.OpenDrain = GPIO_PUSHPULL;	
	gpio_initStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
	gpio_initStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
	gpio_initStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
	gpio_initStruct.Pull = GPIO_PULLUP;
	gpio_initStruct.Alternate = 0;//GPIO_AF5_UART0_RXD;
    HAL_GPIO_Init(GPIOB, &gpio_initStruct);

	gpio_initStruct.Pin = GPIO_PIN_4;
    gpio_initStruct.Mode = GPIO_MODE_AF;
	gpio_initStruct.Alternate = GPIO_AF5_UART0_TXD;
    HAL_GPIO_Init(GPIOB, &gpio_initStruct);	
	
	//HAL_NVIC_EnableIRQ(UART0_IRQn);
}

void app_uart_left_rx_enable(void)
{
    /**if UARTx is UART0 
    PB5     ------> UART0_RXDOpenDrain
    PB4     ------> UART0_TXD
    */
    
    GPIO_InitTypeDef gpio_initStruct;
    gpio_initStruct.Pin = GPIO_PIN_5;  
    gpio_initStruct.Mode = GPIO_MODE_AF;
	gpio_initStruct.OpenDrain = GPIO_OPENDRAIN;	
	gpio_initStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
	gpio_initStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
	gpio_initStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
//	if(sy8820.sy880x_vor_open_flag)
//		gpio_initStruct.Pull = GPIO_PULLUP;
//	else
	gpio_initStruct.Pull = GPIO_NOPULL;
	gpio_initStruct.Alternate = GPIO_AF5_UART0_RXD;
    HAL_GPIO_Init(GPIOB, &gpio_initStruct);
		
    gpio_initStruct.Pin = GPIO_PIN_4;
    gpio_initStruct.Mode = GPIO_MODE_INPUT;
	gpio_initStruct.Alternate = 0;
    HAL_GPIO_Init(GPIOB, &gpio_initStruct);
}

void app_uart_left_tx_rx_disable(void)
{
    /**if UARTx is UART0 
    PB5     ------> UART0_RXDOpenDrain
    PB4     ------> UART0_TXD
    */
    
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_4|GPIO_PIN_5);
	
    gpio_initStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;  
    gpio_initStruct.Mode = GPIO_MODE_INPUT;
    gpio_initStruct.OpenDrain = GPIO_OPENDRAIN;	
    gpio_initStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    gpio_initStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
    gpio_initStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
    gpio_initStruct.Pull = GPIO_NOPULL;
    gpio_initStruct.Alternate = 0;
    HAL_GPIO_Init(GPIOB, &gpio_initStruct);
    //HAL_GPIO_WritePin(GPIOB,UARTx_RX_PIN,GPIO_PIN_RESET);
}

#define LENGTH 16
static uint8_t ucSendData[LENGTH] = {0};
static uint8_t ucReceiveData[LENGTH] = {0};
//static uint8_t ucRxCompleteFlag = 0;

void app_uart_left_init(void)
{
	/* Peripheral clock enable */
	__HAL_RCC_UART0_CLK_ENABLE();	
	/* Enable the GPIO_LED Clock */
	__HAL_RCC_GPIOB_CLK_ENABLE();	

	app_uart_left_tx_enable();
	//app_uart_left_rx_enable();
    
	sUartxHandle.Instance = UART0;
	sUartxHandle.Init.BaudRate = 115200;
	sUartxHandle.Init.BaudDouble = UART_BAUDDOUBLE_ENABLE;	
	sUartxHandle.Init.WordLength = UART_WORDLENGTH_8B;
	sUartxHandle.Init.Parity = UART_PARITY_NONE;
	sUartxHandle.Init.Mode = UART_MODE_TX_RX;
	HAL_UART_Init(&sUartxHandle);
	//app_switch_ear_loadmode(HEADEST_L);

	//__HAL_UART_ENABLE_IT(&sUartxHandle, UART_IT_TC | UART_IT_RXNE);
	//HAL_UART_Transmit_IT(&sUartxHandle, ucSendData, sizeof(ucSendData));
	//HAL_UART_Receive_IT(&sUartxHandle, ucReceiveData, sizeof(ucReceiveData));
    
	//HAL_NVIC_SetPriority(UART0_IRQn, PRIORITY_HIGHEST);
	HAL_NVIC_EnableIRQ(UART0_IRQn);
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    //printf("Tx end\n");
    app_uart_left_rx_enable();
    HAL_UART_Receive_IT(&sUartxHandle, ucReceiveData, 7);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//ucRxCompleteFlag = 1;
    printf("Rx: %x,%x,%x,%x,%x,%x,%x\n", ucReceiveData[0], ucReceiveData[1], ucReceiveData[2], ucReceiveData[3]
        , ucReceiveData[4], ucReceiveData[5], ucReceiveData[6]);
    //printf("Rx end\n");
    
    //HAL_UART_Receive_IT(&sUartxHandle, ucReceiveData, sizeof(ucReceiveData));
}

void app_uart_left_deinit(void)
{
	HAL_UART_DeInit(&sUartxHandle);
	/* Enable the LPUART Data Register not empty Interrupt */
    __HAL_UART_DISABLE_IT(&sUartxHandle, UART_IT_RXNE);
	HAL_NVIC_DisableIRQ(UART0_IRQn);
}

void app_uart_right_tx_mode_enable(void)
{
	GPIO_InitTypeDef gpio_initStruct;

	__HAL_RCC_GPIOC_CLK_ENABLE();
    /**if LPUARTx is LPUART 
		GPIO Configuration:    
    PC5     ------> LPUART_TXD
    PC6     ------> LPUART_RXD
    */
    gpio_initStruct.Pin = GPIO_PIN_5;
    gpio_initStruct.Mode = GPIO_MODE_AF;
	gpio_initStruct.OpenDrain = GPIO_OPENDRAIN;	
	gpio_initStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
	gpio_initStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
	gpio_initStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
//	if(sy8820.sy880x_vol_open_flag)
//		gpio_initStruct.Pull = GPIO_PULLUP;
//	else
	gpio_initStruct.Pull = GPIO_NOPULL;
	gpio_initStruct.Alternate = GPIO_AF5_LPUART_TXD;
    HAL_GPIO_Init(LPUARTx_RX_PORT, &gpio_initStruct);
		
//    __HAL_RCC_LPUARTx_TXGPIO_CLK_ENABLE();		
    gpio_initStruct.Pin = GPIO_PIN_6;
    gpio_initStruct.Mode = GPIO_MODE_INPUT;
	gpio_initStruct.Alternate = 0;//GPIO_AF5_LPUART_TXD;
    HAL_GPIO_Init(LPUARTx_RX_PORT, &gpio_initStruct);	
}


void app_uart_right_rx_mode_enable(void)
{
	GPIO_InitTypeDef gpio_initStruct;

	__HAL_RCC_GPIOC_CLK_ENABLE();
    /**if LPUARTx is LPUART 
		GPIO Configuration:    
    PC5     ------> LPUART_TXD
    PC6     ------> LPUART_RXD
    */
    gpio_initStruct.Pin = LPUARTx_RX_PIN;
    gpio_initStruct.Mode = GPIO_MODE_AF;
	gpio_initStruct.OpenDrain = GPIO_OPENDRAIN;	
	gpio_initStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
	gpio_initStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
	gpio_initStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
//	if(sy8820.sy880x_vol_open_flag)
//		gpio_initStruct.Pull = GPIO_PULLUP;
//	else
	gpio_initStruct.Pull = GPIO_NOPULL;
	gpio_initStruct.Alternate = GPIO_AF5_LPUART_RXD;
    HAL_GPIO_Init(LPUARTx_RX_PORT, &gpio_initStruct);
		
//    __HAL_RCC_LPUARTx_TXGPIO_CLK_ENABLE();		
//    gpio_initStruct.Pin = LPUARTx_TX_PIN;
//    gpio_initStruct.Mode = GPIO_MODE_AF;
//		gpio_initStruct.Alternate = LPUARTx_TX_ALTERNATE_AFn;
//    HAL_GPIO_Init(LPUARTx_TX_PORT, &gpio_initStruct);	
}

void app_uart_right_rx_mode_disable(void)
{
    /**if UARTx is UART0 
		GPIO Configuration:    
    PB5     ------> UART0_RXDOpenDrain
    PB4     ------> UART0_TXD
    */
    HAL_GPIO_DeInit(LPUARTx_RX_PORT, LPUARTx_RX_PIN);
	
	gpio_initStruct.Pin = LPUARTx_RX_PIN;  
    gpio_initStruct.Mode = GPIO_MODE_INPUT;
	gpio_initStruct.OpenDrain = GPIO_OPENDRAIN;	
	gpio_initStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
	gpio_initStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
	gpio_initStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
	gpio_initStruct.Pull = GPIO_PULLDOWN;
	gpio_initStruct.Alternate = GPIO_AF5_LPUART_RXD;
    HAL_GPIO_Init(LPUARTx_RX_PORT, &gpio_initStruct);
	HAL_GPIO_WritePin(LPUARTx_RX_PORT,LPUARTx_RX_PIN,GPIO_PIN_RESET);
}

void app_uart_right_init(void)
{
	/* Peripheral clock enable */
	__HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_LPUART_CLK_ENABLE();

	app_uart_right_tx_mode_enable();
		
	sLPUartxHandle.Instance = LPUART;
	sLPUartxHandle.Init.BaudRate = 115200;
	sLPUartxHandle.Init.BaudDouble = UART_BAUDDOUBLE_ENABLE;
	sLPUartxHandle.Init.WordLength = LPUART_WORDLENGTH_8B;
	sLPUartxHandle.Init.Parity = LPUART_PARITY_NONE;
	sLPUartxHandle.Init.LowPowerMode = LPUART_MODE_NORMAL;	
	sLPUartxHandle.Init.Mode = LPUART_MODE_TX_RX;
	sLPUartxHandle.Init.ClkSel = LPUART_CLOCK_PCLK;
	sLPUartxHandle.Init.ClkDiv = LPUART_CLOCK_DIV1;
	HAL_LPUART_Init(&sLPUartxHandle);
	//app_switch_ear_loadmode(HEADEST_R);
	//HAL_NVIC_SetPriority(LPUART_IRQn, PRIORITY_HIGHEST);
	//HAL_NVIC_EnableIRQ(LPUART_IRQn);
}

void app_uart_right_deinit(void) 
{
	HAL_LPUART_DeInit(&sLPUartxHandle);
	/* Enable the LPUART Data Register not empty Interrupt */
    __HAL_LPUART_DISABLE_IT(&sLPUartxHandle, LPUART_IT_RXNE);
	HAL_NVIC_DisableIRQ(LPUART_IRQn);
}


void app_uart_send_data(uint8_t type, uint8_t *data, uint8_t len)
{
	if(type == EARBUD_TYPE_L)
	{
		//HAL_UART_Transmit_IT(&sUartxHandle,dat,len);
		//while(sUartxHandle.gState != HAL_UART_STATE_READY);
		//app_switch_left_ear_rxmode();
        
		//HAL_UART_Transmit(&sUartxHandle, data, len, 1000);

        app_uart_left_tx_enable();
        memcpy(ucSendData, data, len);
        HAL_UART_Transmit_IT(&sUartxHandle, ucSendData, len);
	}
	else
	{
        //HAL_LPUART_Transmit_IT(&sLPUartxHandle, data, len);
		//while(sLPUartxHandle.gState != HAL_LPUART_STATE_READY);
		//app_switch_right_ear_rxmode();

		HAL_LPUART_Transmit(&sLPUartxHandle, data, len, 100);
	}
    
#if 0
	printf("send len:%d,data:", len);
	for (uint8_t i=0; i<len; i++)
	{
		printf(" %02x", dat[i]);
	}
	printf("\r\n");
#endif
}

